import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.senior_homework.viewmodel.MyViewModel

/*
*author:guyueyuan
*createTime:2024/11/17
*/

//private lateinit var myViewModelFactoryHilt:MyViewModelFactoryHilt

@Composable
fun MyApp() {

    val navController= rememberNavController()

//    这样构建只有在hilt中才可以，一般的方式中更多的是构建器，要传入application等等的
//    不同viewmodel的区分，就相关ioc注解和具体viewModel类名就行了
    val viewModel: MyViewModel = viewModel()
    val viewModel_2: MyViewModel = viewModel()

    if (viewModel.getNavController()==null){
        viewModel.setNavController(navController)
    }
//    okk，测试通过，就是同一个对象，nav也加进去了
    Log.i("current_ad","ViewModel address_1: ${System.identityHashCode(viewModel)}")
    Log.i("current_ad","ViewModel address_2: ${System.identityHashCode(viewModel_2)}")
    Log.i("current_lc","lc_1 is ：$LocalViewModelStoreOwner.current")

    LaunchedEffect(Unit) {
        viewModel.checkUploadDatas()
    }

//    研究了内存才知道，后面这个空不能直接使用navController
    NavHost(viewModel.getNavController()!!, startDestination = "shows") {
        composable("shows"){
            Shows(viewModel)
        }
        composable("show_details/{id}", arguments = listOf(navArgument("id"){ type = NavType.IntType })){
            it.arguments?.getInt("id")?.let { it1 -> ShowDetails(it1,viewModel) }
        }
    }
}


//在 Android 开发中，访问数据库的操作不应该在主线程（UI 线程）上执行，因为这可能会导致 UI 冻结，影响用户体验。
//  是会直接报错的，不允许这样操作
@Preview
@Composable
fun MyAppPre() {}

//当你使用 ViewModelProvider 获取 ViewModel 实例时，如果 ViewModel 已经存在，ViewModelProvider 会返回现有的实例，而不是重新创建一个新的实例。
//这意味着即使 Activity 被销毁并重新创建，ViewModel 仍然保持不变。

//具体来说，ViewModelProvider 会根据生命周期所有者的标识（通常是 Activity 或 Fragment 的实例）来管理 ViewModel 的实例。
// 这样可以确保在同一个生命周期范围内，无论 Activity 或 Fragment 被销毁和重新创建多少次，ViewModel 实例都是同一个。


//你需要确保 NavController 的状态也被正确保存和恢复。NavController 本身已经设计为在配置变化（如屏幕旋转）时保持状态，
//就是说，我把controller写进去后，已经保存住了


//下面这个主要是内存泄露与管理的问题
//你提出的问题非常合理。确实，如果 MyRepository 实例是在 MainActivity 中创建的，
// 而 ViewModel 保持不变，那么每次 Activity 重建时都会创建一个新的 MyRepository 实例，
// 这可能会导致不必要的内存消耗和潜在的内存泄漏。
//为了避免这种情况，最好的做法是将 MyRepository 的创建逻辑移到 ViewModel 中，
// 这样可以确保 Repository 实例在 ViewModel 的生命周期内保持不变。
// 这样不仅避免了重复创建 Repository 实例，还能更好地利用 ViewModel 的生命周期管理功能。


//因为我如果不加@Composable注解，它就不是一个可组合函数，就不能这么使用。
// 只要是可组合函数都可以调用viewModel() 函数去获取ViewModel，
// 而我们这里的就是MainViewModel，viewModel() 会返回一个现有的 ViewModel，或在给定作用域内创建一个新的 ViewModel。
// 只要该作用域处于有效状态，就会保留 ViewModel。例如，如果在某个 Activity 中使用了可组合项，
// 则在该 Activity 完成或进程终止之前，viewModel() 会返回同一实例。这里的作用域很重要，
// 因为普通函数如果没有作用域的话是无法调用可组合函数。